/*****************串口数据接收模块***********************/
/*
自定义变量
rcvok     :1-全部数据接收完成，串口接收结束，退出程序。(标志变量）
synok     :1-头部标识检测成功，正式开始接收数据（标志变量）
rcvBuf[]  ：从SBUF接收1Byte,类开型 unsigned char 。
          （接收业务数据），数组个数业务数据个类+1个数据个数变量（recvBuf[0]）+1个和校验值（recvBuf[recvBuf(0)+1])
inIndex   ：计数变量。
*/
#include "stc15.h"
#include "uart.h"



int unsigned rcvOk;                 //全局变量
int unsigned synOk;
int         inIndex;
int unsigned numb;
int unsigned i;
unsigned char rcvBuf[20]; //全局变量


/********串口波特率，使能初始化***************************/
void Uart_Config(void)
{
    SCON = 0x50;                //8位可变波特率  
	AUXR = 0x40;                //定时器1为1T模式
	TMOD = 0x20;                //定时器1为模式2(8位自动重载)
	TH1 = 0xB8;					//9600
	TL1 = TH1;				    //频率22.1185MHZ
	TR1    = 1;                 //定时器1开
	ES     =  1;                //串口中断开
	EA     =  1;                //总中断开
}


/*********串口接收程序变量初始化**************************/
void Uart_Com_Ini(void)	 	 
{
	rcvOk = 0;               //1-数据接收完成
	inIndex = 0;            //计数变量
	synOk = 0;             //1-数据头部标识检测正确
}


/********串口中断和通迅协议解析*************************/
void Uart(void) interrupt 4
{

   if(RI)                                                      //串口硬件接收完一个Byte会自动把RI置1，要用软件清零。
   { 
		RI = 0;                                                //RI清零，串口硬件才能继续接收数据
		if(rcvOk) return;                                      //1-数据接收完成，退出程序

		if(synOk)                                             //1-头部标识检测成功
		{				
			if((rcvBuf[0] == 0)|(rcvBuf[0] == 0xff))	   //rcvBuf[0]-数据长度位的干扰过滤
			{
				rcvBuf[0] = SBUF;
				rcvBuf[rcvBuf[0]+1] = rcvBuf[0];	
				return;							  
			}

			else
			{
				rcvBuf[inIndex] = SBUF;				           
			 }

			if((rcvBuf[1] == 0)|(rcvBuf[1] == 0xff))		//rcvBuf[1]-功能位的干扰过滤
			{
				return;                                      
			}
						

			if(inIndex == rcvBuf[0])	                      //数据接收个数等于预定个数，检测长度值和data求和的值是否等于原先的和值
			{
				if(rcvBuf[rcvBuf[0]+1] == rcvBuf[inIndex])    //最后接收到'和校验值'和实际收到的长度+data的和值比较,相同则接收成功，返回接收功能
				{
				   rcvOk = 1;
				   inIndex = 0;	                              //rcvok=1 接收数据正确，根据接收到的数据执行行具体业务流程
				   synOk = 0;  
			   }
			   else
			   {
				  Uart_Com_Ini();
			   }
			}	 
			else
			{
			  rcvBuf[rcvBuf[0]+1] += rcvBuf[inIndex];				  //数据个数值和data的求和
			  inIndex++;
			}
		}
		else
		{
			rcvBuf[inIndex] = SBUF;

			if((rcvBuf[inIndex] == 0)|(rcvBuf[inIndex] == 0xff))
			{
				inIndex -= 1; // 把输入是0或0xff干扰过滤掉
			}
			


			if(inIndex == 4)  //前面已经接收0，1，2，3四个数据
			{
			 	if((rcvBuf[inIndex-4] == 0xb1) && (rcvBuf[inIndex-3] == 0xc8) 
				&& (rcvBuf[inIndex-2] == 0xb6) && (rcvBuf[inIndex-1] == 0xfb))
				{
				   synOk = 1;                           //头部标识检测成功，防止误码和干扰			   
				   rcvBuf[0] = rcvBuf[inIndex];         //业务数据的长度，保存到rcvBuf[0]
				   inIndex = 1;                         //计数变量从1重新开始计数，

				   rcvBuf[rcvBuf[0]+1] = rcvBuf[0];		  //rcvBuf[rcvBuf[0]+1]是接收方累积求和变量，先把数据个数值存进去
				} 
				else
				{
					inIndex = 0;
				}	
			}
			else
			{
				inIndex++;	
			}
		} 		
	}
	else if(TI)
	{
	   TI = 0;//发送中断标志初始化

       if(trsLen--)//trsLen是要发送的8位数据的个数，在发数据之前要计算出数组中实际存放数据的个数
       {
          SBUF = *trsP;//保存要发送数据的数组的首地址
          trsP++;     //指针自动下移到下一个数组成员                            
                                    
       }
        
                
                             
    }		
}

